package com.yanqu.road.server.manager.activity.zhenhuan;

import com.yanqu.road.dao.impl.activity.zhenhuan.CrossZhenHuanPartyImpl;
import com.yanqu.road.dao.impl.activity.zhenhuan.CrossZhenHuanPartyJoinImpl;
import com.yanqu.road.entity.activity.zhenhuan.config.ZhenHuanLevelConfig;
import com.yanqu.road.entity.activity.zhenhuan.config.ZhenHuanNpcConfig;
import com.yanqu.road.entity.activity.zhenhuan.secondProcess.CrossZhenHuanPartyData;
import com.yanqu.road.entity.activity.zhenhuan.secondProcess.CrossZhenHuanPartyJoinData;
import com.yanqu.road.logic.activity.zhenhuan.ZhenHuanSecondProcessConfig;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CrossZhenHuanPartyInfo {
    private long partyId;
    private CrossZhenHuanPartyData partyData;
    //key userId
    private Map<Long, CrossZhenHuanPartyJoinData> joinDataMap = new HashMap<>();
    //key pos
    private Map<Integer, Long> posUserIdMap = new HashMap<>();

    private long sortPrestige; //排序用的威望奖励
    private int sortJoinNum; //排序用的参与人数

    public CrossZhenHuanPartyInfo(CrossZhenHuanPartyData partyData, Map<Long, CrossZhenHuanPartyJoinData> joinDataMap) {
        this.partyId = partyData.getPartyId();
        this.partyData = partyData;
        this.joinDataMap = joinDataMap;

        for (CrossZhenHuanPartyJoinData joinData : joinDataMap.values()) {
            posUserIdMap.put(joinData.getPos(), joinData.getUserId());
        }
    }

    public long getPartyId() {
        return partyId;
    }

    public CrossZhenHuanPartyData getPartyData() {
        return partyData;
    }

    public void setPartyData(CrossZhenHuanPartyData partyData) {
        this.partyData = partyData;
    }

    public Map<Long, CrossZhenHuanPartyJoinData> getJoinDataMap() {
        return joinDataMap;
    }

    public void setJoinDataMap(Map<Long, CrossZhenHuanPartyJoinData> joinDataMap) {
        this.joinDataMap = joinDataMap;
    }

    public synchronized boolean isFull(int fullNum) {
        return getJoinNum() >= fullNum;
    }

    public synchronized boolean isTimeEnd() {
        return DateHelper.getCurrentTime() >= partyData.getEndTime();
    }

    public boolean isFinish() {
        if (partyData.getFinishTime() > 0){
            return true;
        }
//        long currentTime = DateHelper.getCurrentTime();
//        if (currentTime >= partyData.getEndTime() && isFull(fullNum)) {
//            return true;
//        }
        return false;
    }

    public boolean isUserJoin(long userId) {
        if (partyData.getUserId() == userId) {
            return true;
        }
        return joinDataMap.containsKey(userId);
    }

    public long getPartyEndTime() {
        if (partyData.getFinishTime() != 0) {
            return partyData.getFinishTime();
        }
        return partyData.getEndTime();
    }

    public synchronized int getJoinNum() {
        return joinDataMap.size() - 1;
    }

    public synchronized List<CrossZhenHuanPartyJoinData> getJoinList() {
        List<CrossZhenHuanPartyJoinData> list = new ArrayList<>();

        list.addAll(joinDataMap.values());

        return list;
    }

    //新加入的玩家
    public synchronized CrossZhenHuanJoinResult joinUser(int pos, long userId, int userLevel, long userPrestige,long targetUserId, ZhenHuanSecondProcessConfig config) {
        CrossZhenHuanJoinResult result = new CrossZhenHuanJoinResult(partyId, 0, pos, userId, userLevel, userPrestige);
        if (isUserJoin(userId)) {
            return result.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_USER_ALREADY_JOIN);
        }

        if (isFinish()){
            return result.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_PARTY_TIME_END);
        }

        if (isTimeEnd()) {
            return result.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_PARTY_TIME_END);
        }

        if (targetUserId != 0 && !isFull(config.getPartyCanJoinNum())) {
            return result.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_PARTY_NOT_FULL);
        }

        CrossZhenHuanPartyJoinData joinData = null;
        boolean originFull = isFull(config.getPartyCanJoinNum());

        if (posUserIdMap.containsKey(pos)) {
            if (targetUserId == 0) {//客户端觉得位置上没人
                return result.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_POS_ALREADY_JOIN);
            } else {
                Long alreadyInUserId = posUserIdMap.get(pos);
                if (alreadyInUserId != targetUserId) {
                    //客户端想踢的人和位置上的人不一致
                    return result.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_POS_NOT_TARGET);
                }

                //踢人流程,数据替换
                joinData = joinDataMap.get(alreadyInUserId);
                //判断等级
                if (userLevel < joinData.getUserLevel()) {
                    return result.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_KICK_NOT_STRONGER_THAN);
                }
                //等级一致判断威望
                if (userLevel == joinData.getUserLevel()) {
                    if (userPrestige <= joinData.getUserPrestige()) {
                        return result.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_KICK_NOT_STRONGER_THAN);
                    }
                }
                result.setDefendUserId(alreadyInUserId);
                result.setDefendLevel(joinData.getUserLevel());
                result.setDefendPrestige(joinData.getUserPrestige());

                joinData.setUserId(userId);
                joinData.setUserLevel(userLevel);
                joinData.setJoinTime(DateHelper.getCurrentTime());
                joinData.setUserPrestige(userPrestige);
                joinData.setMatchPrestige(0);

                joinDataMap.remove(targetUserId);
                joinDataMap.put(userId, joinData);
                posUserIdMap.put(pos, userId);
            }
        } else {
            if (targetUserId != 0) {//客户端发包认为有人
                return result.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_POS_NOT_TARGET);
            }
            joinData = new CrossZhenHuanPartyJoinData(config.getActivityId(), partyId, pos, userId);
            joinData.setUserLevel(userLevel);
            joinData.setUserPrestige(userPrestige);
            joinData.setJoinTime(DateHelper.getCurrentTime());

            joinDataMap.put(userId, joinData);
            posUserIdMap.put(pos, userId);
        }

//        allotPrestigeDegree(config);

        //第一次满座, 进入抢座状态, 更新结束时间
        if (!originFull && isFull(config.getPartyCanJoinNum())) {
            partyData.setEndTime(config.calcPartyKickEndTime(partyData.getLevel()));
        }

        return result;
    }

    //重新分配威望
//    public synchronized void allotPrestigeDegree(ZhenHuanSecondProcessConfig config) {
//        long totalPrestige = partyData.getTotalPrestige();
//
//        if (isFull(config.getPartyCanJoinNum())) {
//            //满座奖励
//            ZhenHuanLevelConfig levelConfig = config.getLevelConfig(partyData.getLevel());
//            if (levelConfig != null) {
//                int fullSeatPrestige = levelConfig.getFullSeatReward();
//                CrossZhenHuanPartyJoinData joinData = joinDataMap.get(partyData.getUserId());
//                joinData.setMatchPrestige(fullSeatPrestige);
//            }
//        }
//
//        int totalWeight = 0;
//        for (CrossZhenHuanPartyJoinData joinData : joinDataMap.values()) {
//            if (joinData.getPos() == 1) {//主位不参与分配
//                continue;
//            }
//            ZhenHuanLevelConfig levelConfig = config.getLevelConfig(joinData.getUserLevel());
//            if (levelConfig == null) {
//                continue;
//            }
//            totalWeight += levelConfig.getWeight();
//        }
//
//        for (CrossZhenHuanPartyJoinData joinData : joinDataMap.values()) {
//            if (joinData.getPos() == 1) {//主位不参与分配
//                continue;
//            }
//            ZhenHuanLevelConfig levelConfig = config.getLevelConfig(joinData.getUserLevel());
//            if (levelConfig == null) {
//                continue;
//            }
//
//            int prestige = BigDecimal.valueOf(totalPrestige).multiply(BigDecimal.valueOf(levelConfig.getWeight())).divide(BigDecimal.valueOf(totalWeight), 0, BigDecimal.ROUND_HALF_UP).intValue();
//            totalWeight = totalWeight - levelConfig.getWeight();
//            totalPrestige -= prestige;
//
//            joinData.setMatchPrestige(prestige);
//        }
//    }

    /**
     * 威信奖励数值 = 举办人共享威信度*2 + 所有已参与玩家提供的共享威信度
     * @param config
     */
    public synchronized void calcExtraPrestige(ZhenHuanSecondProcessConfig config) {
        int extraPrestige = 0;
        for (CrossZhenHuanPartyJoinData joinData : joinDataMap.values()) {
            int userLevel = joinData.getUserLevel();
            ZhenHuanLevelConfig levelConfig = config.getLevelConfig(userLevel);
            if (levelConfig == null) {
                continue;
            }

            if (joinData.getPos() == 1){
                extraPrestige += levelConfig.getSharePrestige() * config.getOpenMultiPrestige();
            }else {
                extraPrestige += levelConfig.getSharePrestige();
            }
        }
        partyData.setExtraPrestige(extraPrestige);
    }

    public CrossZhenHuanPartyJoinData getJoinDataByUserId(long userId) {
        return joinDataMap.get(userId);
    }

    public synchronized void updateJoinLevel(long userId, int userLevel, long userPrestige, ZhenHuanSecondProcessConfig config) {
        CrossZhenHuanPartyJoinData joinData = joinDataMap.get(userId);
        if (joinData == null) {
            return;
        }
        int oldLevel = joinData.getUserLevel();
        if (userLevel > joinData.getUserLevel()) {//只会变大,防止先后问题
            joinData.setUserLevel(userLevel);
        }
        if (userPrestige > joinData.getUserPrestige()) {
            joinData.setUserPrestige(userPrestige);
        }

        if (oldLevel != joinData.getUserLevel()) {
            calcExtraPrestige(config);
        }

    }

    public synchronized void endParty(ZhenHuanSecondProcessConfig config) {
        //计算每个玩家获得的总威望 共享总威望
        for (CrossZhenHuanPartyJoinData joinData : joinDataMap.values()) {
            joinData.setMatchPrestige(partyData.getExtraPrestige());
        }

        partyData.setFinishTime(DateHelper.getCurrentTime());
    }

    public void save() {
        if (partyData.isInsertOption()) {
            new CrossZhenHuanPartyImpl().add(partyData);
        } else if (partyData.isUpdateOption()) {
            new CrossZhenHuanPartyImpl().update(partyData);
        }

        List<CrossZhenHuanPartyJoinData> joinList = getJoinList();
        for (CrossZhenHuanPartyJoinData joinData : joinList) {
            if (joinData.isInsertOption()) {
                new CrossZhenHuanPartyJoinImpl().add(joinData);
            } else if (joinData.isUpdateOption()) {
                new CrossZhenHuanPartyJoinImpl().update(joinData);
            }
        }

    }

    public int getPartyLevel() {
//        Long userId = posUserIdMap.get(1);
//        if (userId == null) {
//            return partyData.getLevel();
//        }
//        CrossZhenHuanPartyJoinData joinData = joinDataMap.get(userId);
//        if (joinData == null) {
//            return partyData.getLevel();
//        }
//        return joinData.getUserLevel();
        return partyData.getLevel();
    }

    //把剩余位置填充NPC
    public synchronized boolean fillNpc(ZhenHuanSecondProcessConfig config) {
        if (isFull(config.getPartyCanJoinNum())) {
            return false;
        }

        List<ZhenHuanNpcConfig> npcList = config.randomNpcList();
        if (npcList.isEmpty()) {
            return false;
        }


        int takeNpcIndex = 0;//用索引的方式,配置的NPC不够用的时候退出
        for (int checkPos = 2; checkPos <= config.getPartyCanJoinNum() + 1; checkPos++) {
            if (posUserIdMap.containsKey(checkPos)) {
                continue;
            }

            if (takeNpcIndex >= npcList.size()) {
                break;
            }
            ZhenHuanNpcConfig npcConfig = npcList.get(takeNpcIndex);
            takeNpcIndex++;

            CrossZhenHuanPartyJoinData joinData = new CrossZhenHuanPartyJoinData(config.getActivityId(), partyId, checkPos, npcConfig.getId());
            joinData.setUserLevel(npcConfig.getLevel());
            joinData.setUserPrestige(0);
            joinData.setMatchPrestige(0);
            joinData.setJoinTime(DateHelper.getCurrentTime());
            joinData.setIsNpc(1);

            joinDataMap.put(joinData.getUserId(), joinData);
            posUserIdMap.put(joinData.getPos(), joinData.getUserId());
        }

        calcExtraPrestige(config);

        return true;
    }

    //填充指定数量的NPC
    public void fillNpc(ZhenHuanSecondProcessConfig config, int num) {
        if (isFull(config.getPartyCanJoinNum())) {
            return;
        }

        List<ZhenHuanNpcConfig> npcList = config.randomNpcList();
        if (npcList.isEmpty()) {
            return;
        }

        List<ZhenHuanNpcConfig> filterNpcList = new ArrayList<>();
        for (ZhenHuanNpcConfig npcConfig : npcList) {
            if (posUserIdMap.containsKey(npcConfig.getId())) {
                continue;
            }
            filterNpcList.add(npcConfig);
        }

        int takeNpcIndex = 0;//用索引的方式,配置的NPC不够用的时候退出
        for (int checkPos = 2; checkPos <= config.getPartyCanJoinNum() + 1; checkPos++) {
            if (posUserIdMap.containsKey(checkPos)) {
                continue;
            }

            if (takeNpcIndex >= filterNpcList.size()) {
                break;
            }

            ZhenHuanNpcConfig npcConfig = filterNpcList.get(takeNpcIndex);
            takeNpcIndex++;

            CrossZhenHuanPartyJoinData joinData = new CrossZhenHuanPartyJoinData(config.getActivityId(), partyId, checkPos, npcConfig.getId());
            joinData.setUserLevel(npcConfig.getLevel());
            joinData.setUserPrestige(0);
            joinData.setMatchPrestige(0);
            joinData.setJoinTime(DateHelper.getCurrentTime());
            joinData.setIsNpc(1);

            joinDataMap.put(joinData.getUserId(), joinData);
            posUserIdMap.put(joinData.getPos(), joinData.getUserId());

            num--;
            if (num <= 0) {
                break;
            }
        }

        calcExtraPrestige(config);

        if (isFull(config.getPartyCanJoinNum())) {
            partyData.setEndTime(config.calcPartyKickEndTime(partyData.getLevel()));
        }
    }



    public long getSortPrestige() {
        return sortPrestige;
    }

    public void setSortPrestige(long sortPrestige) {
        this.sortPrestige = sortPrestige;
    }

    public int getSortJoinNum() {
        return sortJoinNum;
    }

    public void setSortJoinNum(int sortJoinNum) {
        this.sortJoinNum = sortJoinNum;
    }
}
